Skip to content

feat(update): install-source-aware self-update subcommand#7

Merged
kreneskyp merged 2 commits into
mainfrom
feat/update-subcommand
Jun 20, 2026
Merged

feat(update): install-source-aware self-update subcommand#7
kreneskyp merged 2 commits into
mainfrom
feat/update-subcommand

Conversation

@kreneskyp

Copy link
Copy Markdown
Contributor

What

Adds a `quire update` subcommand that upgrades the installed binary to the latest published version, plus a fix for a pre-existing flaky test on `main`.

`quire update [--check] [--registry ]`

Because quire ships through two channels — the npm prebuilt-binary wrapper (`@agent-ix/quire-cli`) and `cargo install --git` — `update` detects how the running binary was installed (from `current_exe`: a `node_modules` path component → npm, `.cargo` → cargo, else unknown) and drives the matching package manager:

  • npm: `npm view` / `npm install -g @agent-ix/quire-cli@latest`
  • cargo: `cargo install --git … --force`
  • unknown (tarball on PATH, dev build): prints manual instructions, exits 0, touches no network

No cross-scheme version diff — the npm-wrapper and Cargo versions are independently numbered, so idempotency is delegated to npm/cargo. A `--registry` override is applied as the scope-specific `--@agent-ix:registry=` form (a plain `--registry` is silently ignored for a scoped package when npmrc pins a scope registry); with no override the ambient npm config resolves the package.

Two-layer structure (kit-ready)

  • `src/self_update/mod.rs` — package-agnostic engine (config-struct driven, no quire `io`/ctx coupling, returns a `SelfUpdateReport`). Intended to extract verbatim into a future shared Rust CLI kit.
  • `src/commands/update.rs` — thin quire wrapper supplying quire's distribution coordinates.

Deliberate exception to the quire-rs thin boundary (StR-004): this manages binary lifecycle, not artifact behavior, so it carries no parser/validator logic and wraps no `quire-rs` API.

Flaky-test fix (separate commit)

`edit_rejects_doc_and_content_both_stdin` raced the child's early exit and intermittently panicked with `BrokenPipe` (the failure on `main`'s last CI run). Tolerate the expected BrokenPipe; the real assertions are unchanged.

Spec

  • New FR-016 (`spec/functional/FR-016-update-subcommand.md`, implements StR-001) + index/log.
  • FR-016 AC→test traceability added to `spec/tests.md` (with honest ⚠️ for the side-effecting npm/cargo install + registry-unreachable paths that have no automated test).

Tests

  • Unit: `detect_source` (incl. lookalike-path false-positive guard), `registry_args` scope/plain/empty, cargo-`--check`, unknown-manual.
  • Integration (`tests/cli_update.rs`): unknown-source manual path, exit 0, no install.
  • Full `make ci` green; bench p95 ≈ 4.7 ms (budget 50 ms).

🤖 Generated with Claude Code

Agent IX and others added 2 commits June 20, 2026 13:46
quire edit - --content - rejects the both-stdin-args combination before it
reads stdin, so the test's write_all raced the child's exit and panicked with
BrokenPipe when the child won (intermittent CI failure on main). Tolerate the
expected BrokenPipe; the real assertions (exit 1 + stderr message) are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
quire update upgrades the installed binary to the latest published version.
Because quire ships via two channels (npm prebuilt-binary wrapper and
cargo install --git), it detects the install source from the running
executable path (node_modules -> npm, .cargo -> cargo, else unknown) and
drives the matching package manager; an unknown source prints manual
instructions and exits 0 without touching the network.

The logic lives in a package-agnostic self_update engine (config-struct
driven, no quire coupling) so it can later extract into a shared Rust CLI
kit; commands/update.rs is the thin quire wrapper. No cross-scheme version
diff (npm wrapper and Cargo versions are decoupled) -- idempotency is
delegated to npm/cargo. A --registry override is applied as the
--@agent-ix:registry= scope form (a plain --registry is ignored for a
scoped package when npmrc pins a scope registry).

Adds FR-016 + tests.md traceability. Deliberate exception to the quire-rs
thin boundary (StR-004): binary lifecycle, not artifact behavior.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kreneskyp kreneskyp requested a review from a team as a code owner June 20, 2026 20:46
@kreneskyp kreneskyp merged commit 17cac32 into main Jun 20, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant